﻿/// <reference path="BaseComplexListControl.js" />
/// <reference path="../General/CSS.js" />


var $ComboBox = TA.Turbo.Controls.ComboBox = function ComboBox(clientId)
{
	if (Function.IsInherit(arguments)) return;

	this.BaseComplexListControl(clientId);
}
$ComboBox.Inherit(TA.Turbo.Controls.BaseComplexListControl);

var _____a;
if (_____a)
{
	$ComboBox.prototype = new $BaseComplexListControl();
	$ComboBox.prototype.BaseComplexListControl = new $BaseComplexListControl();

	$ComboBox.prototype._input = document.createElement("INPUT");
	$ComboBox.prototype._button = document.createElement("IMG");
	$ComboBox.prototype._list = document.createElement("DIV");
	$ComboBox.prototype._options = new Array();
}

$PropertyDefinition.Define($ComboBox, "Editable", "Ed", true);

// VARS
$ComboBox.prototype._listShown = false;
$ComboBox.prototype._mouseDown = false;
$ComboBox.prototype._buttonMouseDown = false;
$ComboBox.prototype._selected = null;


// PUBLIC
// PROPS
$ComboBox.prototype.get_ItemsContainer = function get_ItemsContainer()
{
	return this._list;
}
$ComboBox.prototype.get_ListShown = function get_ListShown()
{
	return this._listShown;
}
$ComboBox.prototype.set_ListShown = function set_ListShown(flag)
{
	this._listShown = flag;
	this._list.style["visibility"] = this._listShown ? "visible" : "hidden";

	this._InputToSelection();
	if (this._listShown)
	{
		document.AddEvent("mousedown", this._document_MouseDown, this);
		document.AddEvent("mouseup", this._document_MouseUp, this);
		document.AddEvent("keypress", this._document_KeyPress, this);
	}
	else
	{
		document.RemoveEvent("mousedown", this._document_MouseDown, this);
		document.RemoveEvent("mouseup", this._document_MouseUp, this);
		document.RemoveEvent("keypress", this._document_KeyPress, this);
	}
}
$ComboBox.prototype.get_Value = function get_Value()
{
	var v = this._input.value.toLowerCase();

	for (var iOption = 0; iOption < this._options.length; ++iOption)
	{
		var option = this._options[iOption];

		if (option.getAttribute("text").toLowerCase() == v)
			return option.getAttribute("value");
	}

	return v;
}
$ComboBox.prototype.set_Value = function set_Value(value)
{
	for (var iOption = 0; iOption < this._options.length; ++iOption)
	{
		var option = this._options[iOption];

		if (option.getAttribute("value").toLowerCase() == value)
		{
			this._input.value = option.getAttribute("text");
			return;
		}
	}
	this._input.value = value;
}


// METHODS
$ComboBox.prototype.Init = function Init()
{
	this.BaseComplexListControl.Init.call(this);

	this._options = new Array();
	var cn = this._control.childNodes, cnl = cn.length;
	for (var iChild = 0; iChild < cnl; ++iChild)
	{
		var child = cn[iChild];

		switch (child.tagName)
		{
			case "INPUT":
				this._input = $(child);
				break;
			case "DIV":
				switch (child.className)
				{
					case "list":
						this._list = $(child);
						break;
					case "button":
						this._button = $(child);
						break;
				}
		}
	}

	this._input.AddEvent("keypress", this._input_KeyPress, this);
	this._input.AddEvent("focus", this._input_Focus, this);
	this._input.AddEvent("click", this._input_Click, this);
	this._button.AddEvent("mousedown", this._button_MouseDown, this);
	this._button.AddEvent("mouseup", this._button_MouseUp, this);
	window.AddEvent("blur", this._window_Blur, this);

	this.UpdateInput();

	var myself = this;
	this._list.PerformRecursive(function(elem)
	{
		if ($(elem).HasClass("option"))
		{
			myself._options.push(elem);
			myself._AddOptionHandlers(elem);
		}
	});
}
$ComboBox.prototype.UpdateInput = function UpdateInput()
{
	this._input.RemoveClass("editable");
	this._input.RemoveClass("dropdown");

	if (this.get_Editable())
		this._input.AddClass("editable");
	else
		this._input.AddClass("dropdown");
}



// INTERNAL
// PROPS
$ComboBox.prototype._get_MouseDown = function _get_MouseDown()
{
	return this._mouseDown;
}
$ComboBox.prototype._set_MouseDown = function _set_MouseDown(value)
{
	this._mouseDown = value;
	var se = !this._mouseDown;

	document.set_SelectionEnabled(se);
}
$ComboBox.prototype._get_ButtonMouseDown = function _get_ButtonMouseDown()
{
	return this._buttonMouseDown;
}
$ComboBox.prototype._set_ButtonMouseDown = function _set_ButtonMouseDown(value)
{
	this._buttonMouseDown = value;
	this._set_MouseDown(value);

	if (this._buttonMouseDown)
	{
		this._button.AddEvent("mouseover", this._button_MouseOver, this);
		this._button.AddEvent("mouseout", this._button_MouseOut, this);
	}
	else
	{
		this._button.RemoveEvent("mouseover", this._button_MouseOver, this);
		this._button.RemoveEvent("mouseout", this._button_MouseOut, this);
	}
}
$ComboBox.prototype._get_Selected = function _get_Selected()
{
	return this._selected;
}
$ComboBox.prototype._set_Selected = function _set_Selected(option)
{
	if (this._selected != null)
		this._selected.RemoveClass("selected");
	this._selected = option;
	if (this._selected != null)
		this._selected.AddClass("selected");

}

// METHODS
$ComboBox.prototype._ItemsGetInitValue_Fill = function _ItemsGetInitValue_Fill(collection, container)
{
	var cn = container.childNodes, cnl = cn.length;
	for (var i = 0; i < cnl; ++i)
	{
		var child = cn[i];

		if (child.tagName != "LABEL" && child.tagName != "DIV") continue;

		var item = new $ListItem();
		item.ReadAttributes(child);
		if (cn[i].tagName == "LABEL")
		{
			item.Text = child.innerHTML;
			++i;
			var div = cn[i];
			this._ItemsGetInitValue_Fill(item.Items, div);
		}
		else
		{
			item.Text = child.innerHTML;
			item.Value = child.getAttribute("value");
		}

		collection.push(item);
	}
}
// CREATE ITEMS
$ComboBox.prototype._ClearItems = function _ClearItems()
{
	this.BaseComplexListControl._ClearItems.call(this);

	this._options.length = 0;
}
$ComboBox.prototype._ClearItems_SaveElement = function _ClearItems_SaveElement(elem)
{
	elem.RemoveEvent("mouseup", this._option_MouseUp, this);
}
$ComboBox.prototype._CreateGroupElements = function _CreateGroupElements(item)
{
	var label = this._GetElement("LABEL");

	var elem = this._GetElement("DIV");
	elem.className = "group";

	return [label, elem];
}
$ComboBox.prototype._AddOptionHandlers = function _AddOptionHandlers(elem)
{
	elem.AddEvent("mousedown", this._option_MouseDown, this);
	elem.AddEvent("mouseup", this._option_MouseUp, this);
	elem.AddEvent("mouseover", this._option_MouseOver, this);
}
$ComboBox.prototype._CreateOptionElements = function _CreateOptionElements(item)
{
	var elem = this._GetElement("DIV");
	item.AddAttributes(elem);
	elem.className += " option";
	this._options.push(elem);
	return [elem];
}

// SELECTION
$ComboBox.prototype._InputToSelection = function _InputToSelection()
{
	this._set_Selected(this._GetSelectedOption());
}
$ComboBox.prototype._SelectionToInput = function _SelectionToInput()
{
	if (this._get_Selected() == null)
		this._input.value = "";
	else
	{
		this._input.value = this._get_Selected().getAttribute("text");
		this._input.select(0, this._input.value.length);
	}
}
$ComboBox.prototype._GetSelectedOption = function _GetSelectedOption()
{
	var selected = null;
	for (var iOption = 0; iOption < this._options.length; ++iOption)
	{
		var option = this._options[iOption];

		if (option.getAttribute("text") == this._input.value)
		{
			selected = option;
			break;
		}
	}
	return selected;
}
$ComboBox.prototype._SelectOneUp = function _SelectOneUp()
{
	var sel = null;
	if (this._get_Selected() == null)
		sel = this._options[this._options.length - 1];
	else
	{
		var selectedIndex;
		for (var iOption = 0; iOption < this._options.length; ++iOption)
		{
			if (this._options[iOption] == this._get_Selected())
			{
				selectedIndex = iOption;
				break;
			}
		}

		selectedIndex = (selectedIndex + this._options.length - 1) % this._options.length;
		sel = this._options[selectedIndex];
	}

	this._set_Selected(sel);
}
$ComboBox.prototype._SelectOneDown = function _SelectOneDown()
{
	var sel = null;
	if (this._get_Selected() == null)
		sel = this._options[0];
	else
	{
		var selectedIndex;
		for (var iOption = 0; iOption < this._options.length; ++iOption)
		{
			if (this._options[iOption] == this._get_Selected())
			{
				selectedIndex = iOption;
				break;
			}
		}

		selectedIndex = (selectedIndex + 1) % this._options.length;
		sel = this._options[selectedIndex];
	}

	this._set_Selected(sel);
}
$ComboBox.prototype._Commit = function _Commit()
{
	this._SelectionToInput();

	this.set_ListShown(false);
}


// HANDLERS
$ComboBox.prototype._input_KeyPress = function _input_KeyPress(e)
{
	var k = Events.GetKeyCode(e);
	switch (k)
	{
		case 38: //up
			this._input_KeyPress_Up();
			break;
		case 40: // down
			this._input_KeyPress_Down();
			break;
		default:
			this._set_Selected(null);
			break;
	}
}
$ComboBox.prototype._input_Focus = function _input_Focus(e)
{
	if (!this.get_Editable())
	{
		this._input.blur();
	}
}
$ComboBox.prototype._input_Click = function _input_Click(e)
{
	if (!this.get_Editable())
		this.set_ListShown(!this.get_ListShown());
}
$ComboBox.prototype._input_KeyPress_Up = function _input_KeyPress_Up()
{
	this._SelectOneUp();
	this._SelectionToInput();
}
$ComboBox.prototype._input_KeyPress_Down = function _input_KeyPress_Down()
{
	this._SelectOneDown();
	this._SelectionToInput();
}
$ComboBox.prototype._button_MouseDown = function _button_MouseDown(e)
{
	this._set_ButtonMouseDown(true);
	this._button.AddClass("pushed");
	this.set_ListShown(!this.get_ListShown());

	Events.Stop(e);
}
$ComboBox.prototype._button_MouseUp = function _button_MouseUp(e)
{
	this._set_ButtonMouseDown(false);
	this._button.RemoveClass("pushed");

	Events.Stop(e);
}
$ComboBox.prototype._button_MouseOver = function _button_MouseOver(e)
{
	if (this._get_ButtonMouseDown())
		this._button.AddClass("pushed");

}
$ComboBox.prototype._button_MouseOut = function _button_MouseOut(e)
{
	if (this._get_ButtonMouseDown())
		this._button.RemoveClass("pushed");

}
$ComboBox.prototype._document_MouseDown = function _document_MouseDown(e)
{
	this.set_ListShown(false);
}
$ComboBox.prototype._document_MouseUp = function _document_MouseUp(e)
{
	if (this._get_ButtonMouseDown())
	{
		this._button.RemoveClass("pushed");
		this._set_ButtonMouseDown(false);
	}
	else if (this._get_MouseDown())
	{
		this._button.RemoveClass("pushed");
		this._set_MouseDown(false);
	}
}
$ComboBox.prototype._document_KeyPress = function _document_KeyPress(e)
{
	var k = Events.GetKeyCode(e);
	switch (k)
	{
		case 38: //up
			this._document_KeyPress_Up();
			break;
		case 40: // down
			this._document_KeyPress_Down();
			break;
		case 13:
			this._document_KeyPress_Enter();
			Events.Stop(e);
			Events.Cancel(e);
			break;
	}
}
$ComboBox.prototype._document_KeyPress_Up = function _document_KeyPress_Up()
{
	this._SelectOneUp();
}
$ComboBox.prototype._document_KeyPress_Down = function _document_KeyPress_Up()
{
	this._SelectOneDown();
}
$ComboBox.prototype._document_KeyPress_Enter = function _document_KeyPress_Enter()
{
	this._Commit();
}
$ComboBox.prototype._option_MouseDown = function _option_MouseDown(e)
{
	this._set_MouseDown(true);

	Events.Stop(e);
}
$ComboBox.prototype._option_MouseUp = function _option_MouseUp(e)
{
	this._Commit();

	if (this._get_ButtonMouseDown())
		this._set_ButtonMouseDown(false);
	else if (this._get_MouseDown())
		this._set_MouseDown(false);

	Events.Stop(e);
}
$ComboBox.prototype._option_MouseOver = function _option_MouseOver(e)
{
	this._set_Selected(Events.GetSender(e));
}
$ComboBox.prototype._window_Blur = function _window_Blur(e)
{
	if (this.get_ListShown())
		this.set_ListShown(false);
}

// EVENTS
$ComboBox.prototype._OnEditableChanged = function _OnEditableChanged()
{
	this.UpdateInput();
}

